/*- y tuong "layout": tao su kien onclick bang cach su dung thuoc tinh visibiliti cua hinh anh. Cach thuc hien: step1:
 * tao 2 hinh anh, 1 la anh truoc khi click, 1 la anh sau khi click. step2: sau khi use click hoac goi den function an
 * hinh anh truoc khi click. step3: sau 1 thoi gian (speed) cho hien thi la hinh anh truoc khi click. Preferen:
 * onClickCustom() function. - y tuong "save": khi nhan try again ok --> choi lai. nguoc lai: hien thi thong tin user da
 * choi trong khoang thoi gian qua. */
package ty.tryagainforever1129.pikachumemory;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import ty.tryagainforever1129.pikachumemory.common.Constant;
import ty.tryagainforever1129.pikachumemory.common.Util;
import ty.tryagainforever1129.pikachumemory.list.ItemLayoutList;
import ty.tryagainforever1129.pikachumemory.list.MediaPlayerList;
import ty.tryagainforever1129.pikachumemory.model.UserModel;
import android.media.AudioManager;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;

/** @author tranvanthe. main activity. */
public class MainActivity extends Activity {
    /** main layout. */
    private ItemLayoutList mainLayout;
    /** memory list. */
    private ArrayList<Integer> memoryList;
    /** media list. */
    private MediaPlayerList mediaList;
    /** timer. */
    private Timer timer;
    private int position;
    private int memoryIndex;
    private Random randomInterger;
    /** audio manager, config volume music. */
    AudioManager audio;
    /** user list in the leader boards. */
    ArrayList<UserModel> userList;

    @Override
    protected final void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(Constant.TAG_PLAY, "on create.");
        // create data.
        initData();
        // reset game.
        resetGame();
        Log.i(Constant.TAG_PLAY, "on create finish.");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.a_pikachu_memory, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_settings:
                startActivity(new Intent(MainActivity.this, SettingActivity.class));
                break;
            case R.id.menu_leader_boards:
                displayLeaderBoards(null);
                break;
            default:
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    /** display leader boards. */
    private void displayLeaderBoards(UserModel user) {
        Intent intent = new Intent(MainActivity.this, LeaderBoardActivity.class);
        int intentType = Constant.INTENT_LEADER_BOARDS_CODE_DONOT_ANYTHING;
        if (user != null) {
            // put data to leader board activity.
            intent.putExtra(Constant.INTENT_LEADER_BOARDS_USER_NAME, user.getUserName());
            intent.putExtra(Constant.INTENT_LEADER_BOARDS_SCORE, user.getScrore());
            intentType = Constant.INTENT_LEADER_BOARDS_CODE;
        }
        startActivityForResult(intent, intentType);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == Constant.INTENT_LEADER_BOARDS_CODE) {
            resetGame();
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    /** init data function. */
    private void initData() {
        // create memory list.
        memoryList = new ArrayList<Integer>();
        // create new random.
        randomInterger = new Random();
        // create media list.
        mediaList = new MediaPlayerList(this);
        // init audio manager.
        audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        // check and config for the first time.
        Util.configForTheFirstTime(this);
        // create layout.
        mainLayout = new ItemLayoutList();
        setContentView(mainLayout.createView(this));
        for (int i = 0; i < mainLayout.getListItemLayout().size(); i++) {
            final int index = i;
            mainLayout.getItemLayoutAt(i).getNomal().setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // if animation finish.
                    if (position >= memoryList.size()) {
                        Log.i(Constant.TAG_PLAY, "position >= memory list size");
                        Util.onClickCustom(v);
                        Log.i(Constant.TAG_PLAY, "increate memory index.");
                        // check if item exists in memory list.
                        if (memoryList.get(memoryIndex) != index) {
                            Log.i(Constant.TAG_PLAY, "failed!");
                            // play game over music.
                            mediaList.playMedia(Constant.COMMON_1);
                            // Toast.makeText(MainActivity.this, "Game over", Toast.LENGTH_LONG).show();
                            inputUserNameDialog();
                        } else {
                            // play item click media.
                            mediaList.playMedia(Constant.COMMON_0);
                            memoryIndex++;
                            if (memoryIndex >= memoryList.size()) {
                                // reset memory index.
                                memoryIndex = 0;
                                Log.i(Constant.TAG_PLAY, "create new point.");
                                // create new memory and start animation memory.
                                createNewMemoryPoint();
                            }
                        }
                    }
                }
            });
        }
    }

    private void inputUserNameDialog() {
        // create dialog.
        AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
        dialog.setTitle(R.string.ty_alertdialog_game_over);
        // create input view.
        final EditText view = new EditText(MainActivity.this);
        view.setHint(R.string.ty_alertdialog_user_name_hint);
        view.setText(Util.getHeroName(MainActivity.this));
        // score < min score, view create is null.
        if (checkScoreVisible()) {
            dialog.setView(view);
        } else {                        
            dialog.setView(null);
        }
        // set position button.
        dialog.setPositiveButton(R.string.menu_leader_boards, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                UserModel user = new UserModel();
                if (checkScoreVisible()) {
                    user.setUserName(view.getText().toString());
                    user.setScrore(memoryList.size());
                    Util.setHeroName(MainActivity.this, user.getUserName());
                }
                displayLeaderBoards(user);
            }
        });
        // set negative button.
        dialog.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                resetGame();
            }
        });
        // set on key listener (audio manager).
        dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                return audioManagerCustom(keyCode, false);
            }
        });
        dialog.show();
    }
    private boolean checkScoreVisible() {
        return Util.getMinScore(MainActivity.this) < memoryList.size();
    }

    private boolean audioManagerCustom(int keyCode, boolean returnDefault) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_VOLUME_UP:
                audio.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE,
                        AudioManager.FLAG_SHOW_UI);
                return true;
            case KeyEvent.KEYCODE_VOLUME_DOWN:
                audio.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER,
                        AudioManager.FLAG_SHOW_UI);
                return true;
            default:
                return returnDefault;
        }
    }

    private void resetGame() {
        // clear memory.
        memoryList.clear();
        // reset memory index.
        memoryIndex = Constant.COMMON_0;
        // add new memory.
        memoryList.add(randomInterger.nextInt(Constant.ITEM_LAYOUT_LIST_RULE.length));
        // set counter.
        mainLayout.setCounter(memoryList.size());
        // run memory animation.
        runMemoryList();
    }

    private void createNewMemoryPoint() {
        // add new memory.
        memoryList.add(randomInterger.nextInt(Constant.ITEM_LAYOUT_LIST_RULE.length));
        // run memory animation.
        runMemoryList();
    }

    private void runMemoryList() {
        // reset postion list.
        position = 0;
        // set counter.
        mainLayout.setCounter(memoryList.size());
        // init timer.
        destroyTimer();
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                Log.i(Constant.TAG_PLAY, "Timer run.");
                if (memoryList != null && position < memoryList.size()) {
                    final int index = position;
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Log.i(Constant.TAG_PLAY, "onclick custom at postion:" + position);
                            Util.onClickCustom(mainLayout.getItemLayoutAt(memoryList.get(index)).getNomal());
                        }
                    });
                    position++;
                } else {
                    destroyTimer();
                    Log.i(Constant.TAG_PLAY, "Timer cancel.");
                }
            }
        }, Constant.ITEM_LAYOUT_TIMER_DELAY, Constant.ITEM_LAYOUT_TIMER_SPEED);
    }

    private void destroyTimer() {
        if (timer != null) {
            timer.cancel();
            timer.purge();
            timer = null;
        }
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        switch (event.getKeyCode()) {
            case KeyEvent.KEYCODE_VOLUME_UP:
                audio.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE,
                        AudioManager.FLAG_SHOW_UI);
                return true;
            case KeyEvent.KEYCODE_VOLUME_DOWN:
                audio.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER,
                        AudioManager.FLAG_SHOW_UI);
                return true;
            default:
                return super.dispatchKeyEvent(event);
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return audioManagerCustom(keyCode, super.onKeyDown(keyCode, event));
    }

    @Override
    protected void onDestroy() {
        // destroy audio.
        audio = null;
        // destroy media list.
        mediaList.destroy();
        mediaList = null;
        // destroy random.
        randomInterger = null;
        // destroy main layout.
        mainLayout = null;
        // destroy memory list.
        memoryList = null;
        // destroy timer.
        destroyTimer();
        super.onDestroy();
    }
}
